package core;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;

import lib.Logger;
import lib.Message;
import lib.RequestMessage;
import lib.Symbols;

public class RepeaterHandler extends Thread {
	
	private Vector<Message> history;
	private ServerSocket serverSocket;
	private boolean logoff;
	
	public RepeaterHandler() throws IOException {
		this.history = new Vector<Message>();
		this.serverSocket = new ServerSocket(Symbols.REPEATER_PORT+Symbols.OFFSET_1);
		this.logoff = false;
	}
	
	public void addToHistory(Message message) {
		if(history.size()>Symbols.MAX_HISTORY_SIZE) {
			// if history hits the limit then remove first message
			history.remove(0);
		}
		history.add(message);
	}
	
	public Message findMessageInHistory(byte[] digest) {
		for(Message m : history) {
			if(IntegrityHandler.compareDigests(digest, m.getDigest())) {
				return m;
			}
		}
		return null;
	}
	
	public Message findMessageInHistory(int messageId) {
		for(Message m : history) {
			if(m.getMessageId()==messageId) {
				return m;
			}
		}
		return null;
	}
	
	public void run() {
		Socket client;
		byte[] buffer = new byte[Symbols.MAX_REQUEST_DIM];
		Message message = null;
		
		while(!logoff) {
			try {
				client = serverSocket.accept();
				InputStream in = client.getInputStream();
				OutputStream out = client.getOutputStream();
				in.read(buffer);
				RequestMessage request = MessageHandler.getRequestMessageFrom(buffer);
				
				String log = "Received request from " + client.getInetAddress().getHostAddress() + " to retransmit message ";
				
				if(request.getType()==Symbols.MESSAGE_ID_REQ) {
					message = findMessageInHistory(request.getMessageId());
					log += "number " + request.getMessageId();
					
				} else if(request.getType()==Symbols.MESSAGE_DIGEST_REQ) {
					message = findMessageInHistory(request.getDigest());
					log += "with digest " + IntegrityHandler.byteToHexString(request.getDigest());
					
				}
				
				Logger.println(log + " - found: " + (message!=null));
				
				out.write(MessageHandler.getByteFrom(message));
				out.flush();
				
				client.close();
				in.close();
				out.close();
				
			} catch (IOException e) {
				//e.printStackTrace();
				Logger.println("IOException in Repeaterhandler Thread " + e.getMessage());
			}
		}
	}
	
	public void logoff() {
		logoff = true;
	}

}
